﻿using System.Xml;
using Microsoft.ClearScript.V8;

namespace Vboot.Core.Module.Bpm;

public class BpmProcMainHand : ITransient
{
    public Znode ProcFlow(Zbpm zbpm, List<Znode> list, Znode znode)
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(zbpm.chxml);
        XmlElement rootNode = xmlDoc.DocumentElement;
        //查找当前节点的目标节点，如果已有（比如是驳回返回的）则不需要额外查找
        if (znode.tarno == null)
        {
            foreach (XmlElement node in rootNode.ChildNodes)
            {
                if (node.Name == "sequenceFlow")
                {
                    if (znode.facno == node.GetAttribute("sourceRef"))
                    {
                        znode.tarno = node.GetAttribute("targetRef");
                        break;
                    }
                }
            }
        }
        Zcond zcond=new Zcond();
        zcond.proid=zbpm.proid;
        zcond.modty=zbpm.modty;
        //判断nextNode是否为审批节点
        return NodeFlow(zcond,rootNode, list, znode);
    }

    //节点流转
    //判断节点是否为审批节点，如果为审批节点则取处理人
    //      如果是条件分支，则根据分支条件流转到下一个节点，直到找到审批节点
    private Znode NodeFlow(Zcond zcond,XmlElement rootNode, List<Znode> list, Znode znode)
    {
        if ("NE" == znode.tarno)
        {
            znode.tarna = "结束节点";
            Znode endNode = new Znode();
            endNode.facno = "NE";
            endNode.facna = "结束节点";
            endNode.facty = "end";
            return endNode;
        }

        String userIds = "";
        foreach (XmlElement node in rootNode.ChildNodes)
        {
            if ("task" == node.Name || "userTask" == node.Name)
            {
                //节点为审批节点
                if (znode.tarno == node.GetAttribute("id"))
                {
                    userIds = node.GetAttribute("hamen");
                    znode.tarna = node.GetAttribute("name");
                    //list.add(znode);
                    Znode nextNode = new Znode();
                    nextNode.facno = znode.tarno;
                    nextNode.facna = znode.tarna;
                    nextNode.facty = "review";
                    nextNode.exmen = userIds;
                    nextNode.flway = node.GetAttribute("flway");
                    return nextNode;
                }
            }
            else if ("exclusiveGateway" == node.Name)
            {
                //节点为条件分支
                String nextNodeId = "";
                if (znode.tarno == node.GetAttribute("id"))
                {
                    znode.tarna = node.GetAttribute("name");
                    // list.Add(znode);
                    foreach (XmlElement xnode in rootNode.ChildNodes)
                    {
                        if ("sequenceFlow" == xnode.Name)
                        {
                            if (znode.tarno == xnode.GetAttribute("sourceRef"))
                            {
                                if (checkConds(zcond, xnode.GetAttribute("conds")))
                                {
                                    nextNodeId = xnode.GetAttribute("targetRef");
                                    Console.WriteLine("条件分支转到:" + nextNodeId);
                                    Znode nextNode = new Znode();
                                    nextNode.facno = znode.tarno;
                                    nextNode.facna = znode.tarna;
                                    nextNode.facty = "condtion";
                                    nextNode.tarno = nextNodeId;
                                    list.Add(nextNode);
                                    return NodeFlow(zcond,rootNode, list, nextNode);
                                }
                                
                                // if (checkConds(xnode))
                                // {
                                //     //满足条件时
                                //     nextNodeId = xnode.GetAttribute("targetRef");
                                //     Console.WriteLine("条件分支转到:" + nextNodeId);
                                //     Znode nextNode = new Znode();
                                //     nextNode.facno = znode.tarno;
                                //     nextNode.facna = znode.tarna;
                                //     nextNode.facty = "condtion";
                                //     nextNode.tarno = nextNodeId;
                                //     list.Add(nextNode);
                                //     return NodeFlow(rootNode, list, nextNode);
                                // }
                            }
                        }
                    }

                    break;
                }
            }

            if ("" != userIds)
            {
                break;
            }
        }

        return null;
    }
    
    private bool checkConds(Zcond zcond,string expression)
    {
        if (string.IsNullOrEmpty(expression))
        {
            return false;
        }
        string zformJson = "";
        if (zcond != null)
        {
            Console.WriteLine("modty:"+zcond.modty);
            if (zcond.modty == "oaFlow")
            {
                string sql="select zform id from oa_flow_main where id=@proid";
                zformJson  =  _repo.Context.Ado.SqlQuerySingle<string>(sql, new {proid=zcond.proid});
            }else if (zcond.modty.StartsWith("app_"))
            {
                string sql="select cond id from bpm_proc_cond where id=@proid";
                zformJson  =  _repo.Context.Ado.SqlQuerySingle<string>(sql, new {proid=zcond.proid});
            }
        }
        Console.WriteLine(zformJson);
        if (string.IsNullOrEmpty(zformJson))
        {
            zformJson = "{}";
        }
        string form = "var $=" + zformJson;
        
        bool flag = false;
        using (var engine = new V8ScriptEngine())
        {
            if(expression.Contains(";")){
                engine.Execute(form+";var z=false;"+expression);
            }else{
                engine.Execute(form+";var z="+expression+";");
            }
            flag = engine.Script.z;
        }
        return flag;
    }

    // private bool checkConds(XmlElement it)
    // {
    //     foreach (XmlElement son in it.ChildNodes)
    //     {
    //         if ("extensionElements" == son.Name)
    //         {
    //             Console.WriteLine("进入了：extensionElements");
    //             foreach (XmlElement sun in son.ChildNodes)
    //             {
    //                 if ("executionListener" == sun.Name)
    //                 {
    //                     Console.WriteLine("进入了：executionListener");
    //                     if (!checkCond(sun.GetAttribute("expression")))
    //                     {
    //                         return false;
    //                     }
    //
    //                     break;
    //                 }
    //             }
    //
    //             break;
    //         }
    //     }
    //
    //     return true;
    // }
    //
    // private bool checkCond(string expression)
    // {
    //     Console.WriteLine("条件为：" + expression);
    //     return true;
    // }

    public Znode GetNodeInfo(string chxml, string facno)
    {
        //根据tmpid寻找xml的filename
//         String xml = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"
//                      + "\n<process" +
//                      xmlstr.Split("bpmn2:process")[1].Replace("bpmn2:", "").Replace("activiti:", "") + "process>";
// //        System.out.println(xml);

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(chxml);
        XmlElement rootNode = xmlDoc.DocumentElement;

        foreach (XmlElement node in rootNode.ChildNodes)
        {
            if ("userTask" == node.Name || "task" == node.Name)
            {
                if (facno == node.GetAttribute("id"))
                {
                    Znode znode = new Znode();
                    znode.facno = facno;
                    znode.facna = node.GetAttribute("name");
                    znode.exmen = node.GetAttribute("hamen");
                    znode.flway = node.GetAttribute("flway");
                    znode.facty = "review";
                    return znode;
                }
            }
        }

        return null;
    }

    public Znode CalcTarget(Zcond zcond,string chxml, String facno)
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(chxml);
        XmlElement rootNode = xmlDoc.DocumentElement;
        Znode currNode = new Znode();
        currNode.facno = facno;
        foreach (XmlElement node in rootNode.ChildNodes)
        {
            if ("sequenceFlow" == node.Name)
            {
                if (facno == node.GetAttribute("sourceRef"))
                {
                    currNode.tarno = node.GetAttribute("targetRef");
                    break;
                }
            }
        }

        List<Znode> list = new List<Znode>();
        Znode nextNode = NodeFlow(zcond,rootNode, list, currNode);
        return nextNode;
    }

    public Znode GetFirstNode(string xml, string facno)
    {
        //根据tmpid寻找xml的filename
        xml = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"
              + "\n<process" +
              xml.Split("bpmn2:process")[1].Replace("bpmn2:", "").Replace("activiti:", "") + "process>";
        // Console.WriteLine(xml);

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(xml);
        XmlElement rootNode = xmlDoc.DocumentElement;


        Znode currNode = new Znode();
        currNode.facno = facno;
        foreach (XmlElement node in rootNode.ChildNodes)
        {
            if ("sequenceFlow" == node.Name)
            {
                if (facno == node.GetAttribute("sourceRef"))
                {
                    currNode.tarno = node.GetAttribute("targetRef");
                    break;
                }
            }
        }

        List<Znode> list = new List<Znode>();
        Znode nextNode = NodeFlow(null,rootNode, list, currNode);
        return nextNode;
    }

    public List<ZidNamePid> GetAllLineList(string xml)
    {
        //根据tmpid寻找xml的filename
        xml = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"
              + "\n<process" +
              xml.Split("bpmn2:process")[1].Replace("bpmn2:", "").Replace("activiti:", "") + "process>";
        // Console.WriteLine(xml);

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(xml);
        XmlElement rootNode = xmlDoc.DocumentElement;

        List<ZidNamePid> list = new List<ZidNamePid>();
        foreach (XmlElement node in rootNode.ChildNodes)
        {
            if ("sequenceFlow" == node.Name)
            {
                ZidNamePid zinp = new ZidNamePid();
                zinp.id = node.GetAttribute("id");
                zinp.name = node.GetAttribute("sourceRef");
                zinp.pid = node.GetAttribute("targetRef");
                list.Add(zinp);
            }
        }

        return list;
    }
    
    private readonly SqlSugarRepository<BpmProcMain> _repo;


    public BpmProcMainHand(SqlSugarRepository<BpmProcMain> repo)
    {
        this._repo = repo;
    }
    
}